package com.fs.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.exception.BusinessException;
import com.fs.common.utils.BeanUtils;
import com.fs.user.config.JwtProperties;
import com.fs.user.domain.dto.UserLoginFormDTO;
import com.fs.user.domain.dto.UserRegisterFormDTO;
import com.fs.user.domain.dto.UserUpdateDTO;
import com.fs.user.domain.vo.UserLoginVO;
import com.fs.user.domain.po.User;
import com.fs.user.domain.vo.UserUpdateVO;
import com.fs.user.mapper.UserMapper;
import com.fs.user.service.IUserService;
import com.fs.user.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

import static com.fs.common.constant.SystemConstants.USER_NICK_NAME_PREFIX;
import static com.fs.common.enumeration.BusinessExceptionEnum.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 虎哥
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final PasswordEncoder passwordEncoder;

    private final JwtTool jwtTool;

    private final JwtProperties jwtProperties;

    @Override
    public UserLoginVO login(UserLoginFormDTO loginDTO) {
        // 1.数据校验
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();

        // 2.根据用户名查询
        User user = lambdaQuery().eq(User::getUsername, username).one();

        // 3.校验用户是否存在
        if (user == null) {
            throw new BusinessException(USER_NOT_FOUND);
        }

        // 4.校验密码
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException(USER_OR_PASSWORD_ERROR);
        }

        // 5.生成TOKEN
        String token = jwtTool.createToken(user.getId(), jwtProperties.getTokenTTL());

        // 6.封装VO返回
        return UserLoginVO.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .token(token)
                .build();
    }

    @Override
    public UserLoginVO register(UserRegisterFormDTO userRegisterFormDTO) {
        // 1.创建用户
        User user = User.builder()
                .username(userRegisterFormDTO.getUsername())
                .nickname(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10))
                .password(passwordEncoder.encode(userRegisterFormDTO.getPassword()))
                .createdTime(LocalDateTime.now())
                .updatedTime(LocalDateTime.now())
                .build();
        // 2.保存用户
        save(user);

        // 3.生成TOKEN
        String token = jwtTool.createToken(user.getId(), jwtProperties.getTokenTTL());

        // 4.封装VO返回
        return UserLoginVO.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .nickname(user.getNickname())
                .phone(user.getPhone())
                .email(user.getEmail())
                .token(token)
                .build();
    }

    @Override
    @Transactional
    public UserUpdateVO updateUser(Long userId, UserUpdateDTO updateDTO) {
        // 1. 检查用户是否存在
        User existingUser = getById(userId);
        if (existingUser == null) {
            throw new BusinessException(USER_NOT_FOUND);
        }

        // 2. 构建更新条件
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);

        // 3. 设置需要更新的非空字段
        if (StringUtils.hasText(updateDTO.getPassword())) {
            if (!updateDTO.getPassword().equals(updateDTO.getRepassword())) {
                throw new BusinessException(PASSWORD_NOT_MATCH);
            }
            updateWrapper.set(User::getPassword, passwordEncoder.encode(updateDTO.getPassword()));
        }

        if (StringUtils.hasText(updateDTO.getNickname())) {
            updateWrapper.set(User::getNickname, updateDTO.getNickname());
        }
        if(StringUtils.hasText(updateDTO.getPhone())) {
            updateWrapper.set(User::getPhone, updateDTO.getPhone());
        }
        if (StringUtils.hasText(updateDTO.getEmail())) {
            updateWrapper.set(User::getEmail, updateDTO.getEmail());
        }

        updateWrapper.set(User::getUpdatedTime, LocalDateTime.now());

        // 4. 执行更新
        update(updateWrapper);

        UserUpdateVO vo = BeanUtils.copyProperties(getById(userId), UserUpdateVO.class);
        vo.setUserId(userId);

        return vo;
    }
}
